package haois.security;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import haois.constant.StatusCode;
import haois.constant.daomain.Subject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * Created by haol on 2017/3/16.
 */

public class HandleToken {


    @Value("${spring.profiles.active}")
    private String profiles;

    Logger logger = LoggerFactory.getLogger(HandleToken.class);


    public SecretKey generalKey() {
        String stringKey = profiles + StatusCode.JWT_SECRET;
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 存储当前登录用户的信息到jwt
     *
     * @param subject
     * @return
     */
    public String generalSubject(Subject subject) {
        Gson gson = new Gson();
        return gson.toJson(subject);
    }

    public String generalSubject(Object object) {
        Gson gson = new Gson();
        return gson.toJson(object);
    }

    public Claims parseJWT(String jwt) {
        SecretKey key = generalKey();
        Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(jwt).getBody();
        return claims;
    }

    /**
     * 获取当前登录用户的个人信息
     *
     * @param token
     * @return
     * @throws Exception
     */
    public String getValueByKey(String token, String key) {
        Claims claims = this.parseJWT(token);
        JSONObject jsonArray = JSONObject.parseObject(claims.getSubject());
        String ths = jsonArray.getString(key);
        return ths;
    }

    public String getSubject(String token) {
        Claims claims = this.parseJWT(token);
        return claims.getSubject();
    }

    public Date getIssuedAt(String token) {
        Claims claims = this.parseJWT(token);
        return claims.getIssuedAt();
    }


    public <T> T getObject(String token, Class<T> type) {
        Claims claims = this.parseJWT(token);
        Gson gson = new Gson();
        T obj = gson.fromJson(claims.getSubject(), type);
        return obj;

    }

    public boolean analyzeJWT(String jwt) throws Exception {
        try {
            this.parseJWT(jwt);
            return true;
        } catch (ExpiredJwtException ee) {
            throw new Exception("用户签名信息超过有效期，需重新登录");
        } catch (SignatureException se) {
            throw new Exception("用户签名信息非法，需重新登录");
        } catch (Exception e) {
            throw new Exception("未知错误，需重新登录");
        }
    }

    public String getSubject(HttpServletRequest request, String cookieName, String subKey) {
        String token = HandleCookie.getValueByName(request, cookieName);
        String memberNum = this.getValueByKey(token, subKey);
        return memberNum;
    }

    public String getWebSubject(HttpServletRequest request) {
        return this.getWebSubject(request,StatusCode.SUBJECT_KEY_ACCOUNT);
    }
    public String getWebSubject(HttpServletRequest request,String key) {
        return this.getSubject(request,
                StatusCode.COOKIE_JWT_WEB, key);
    }

}

